<?php

require_once 'config/auth.conf.inc';

/*
 * Class d'authentification
* Version 0.3
*
* Date : 09/08/2010
* Auteur : GUNNING Sky
*/

class Auth {

	private $user = array();
	private $connected;
	private $user_table_name = 'users';
	private $login_name;
	private $salt;
	private $password_name;

	public function __construct($salt=__SALT__, $login_name='auth_login', $password_name='auth_password')
	{
		$this->login_name = $login_name;
		$this->password_name = $password_name;
		$this->salt = $salt;

		if($this->testConnexion() == false)
		{
			$this->connected = false;
		}
	}


	/*
	 * Renvoi si cette personne est connecté ou pas
	*/
	public function is_connected()
	{
		return $this->connected;
	}

	/*
	 * Connexion
	* $email : string (email)
	* $password : string non crypté (mot de passe)
	*/
	public function connect($email, $password)
	{
		$deny_login = NoBF::bruteCheck($email);
		
		if($deny_login == true)
			exit('Trop de tentatives de connexion. Merci de recommencer dans quelques minutes.');
		else
		{
			$email = mysql_real_escape_string($email);

			$sql = "SELECT id,email,password FROM `".$this->user_table_name."` WHERE `email` = '$email' AND `password` = '".md5($this->salt.$password)."' ";
			if(!$res = mysql_query($sql)) {
				exit('Erreur MySQL #'.mysql_errno().' : '.mysql_error());
            }

			if (mysql_num_rows($res) == 1)
			{
				$this->connected = true;
				$this->user = mysql_fetch_assoc($res);

				$this->setSecuredData();
				$this->updateUser($this->user['id'], 1);

				return true;
			}
			else
			{
				NoBF::addTentative($email);
				return false;
			}
		}
	}


	/*
	 * Déconnexion
	*/
	public function disconnect()
	{
		$this->resetSessionData();

		unset($_SESSION[ $this->password_name ]);
		unset($_SESSION[ $this->login_name ]);
		unset($_SESSION['token']);
	}


	// Fonctions privées

	/*
	 * test la connexion en cours
	*/
	private function testConnexion()
	{
		// def des vars à tester
		$toTestToken = '';
		$toTestPassword = '';
		$toTestLogin = '';

		// Conservation d'une connexion via cookie
		if (!empty($_COOKIE[ $this->login_name ]) && !empty($_COOKIE[ $this->password_name ]) && empty($_SESSION[ $this->password_name ])) {
			$toTestLogin = $_COOKIE[ $this->login_name ];
			$toTestPassword = $_COOKIE[ $this->password_name ];
			$toTestToken = $_COOKIE[ 'token' ];
		} elseif (!empty($_SESSION[ $this->password_name ]) && !empty($_SESSION[ $this->login_name ])) {
			$toTestLogin = $_SESSION[ $this->login_name ];
			$toTestPassword = $_SESSION[ $this->password_name ];
			$toTestToken = $_SESSION[ 'token' ];
		}

		// Si le token n'est pas identique au fingerprint du navigateur, on reset tout
		if($toTestToken != $this->fingerprint())
		{
			$this->resetSessionData();
			return false;
		}

		if (!empty($toTestLogin) && !empty($toTestPassword))
		{
			$email = mysql_real_escape_string($toTestLogin);
			$password = mysql_real_escape_string($toTestPassword);

			// test si l'utilisateur existe bien
			$sql = "SELECT id,email,password FROM `".$this->user_table_name."` WHERE `email`='$email' AND `password`='$password'";
			if(!$res = mysql_query($sql))
				exit('Erreur MySQL #'.mysql_errno().' : '.mysql_error());

			if (mysql_num_rows($res) == 1)
			{
				$this->connected = true;
				$this->user = mysql_fetch_assoc($res);

				// Si connexion depuis cookie :: on remet en place les sessions + cookies
				if (empty($_SESSION[ $this->password_name ]) || !empty($_SESSION[ $this->login_name ]))
					$this->setSecuredData();

				$this->updateUser($this->user['id']);

				return true;
			}
			else
			{
				$this->resetSessionData();
				return false;
			}
		}
		else
			return false;
	}

	/*
	 * Génère le token du navigateur en cours
	*/
	private function fingerprint()
	{
		$fingerprint = $this->salt . $_SERVER['HTTP_USER_AGENT'];
		$token = md5($fingerprint . session_id());

		return $token;
	}

	/*
	 * On défini les variables d'identifications
	* token, login et mot de passe
	* !! obligation d'avoir défini $this->user avant de l'utiliser !!
	*/
	private function setSecuredData()
	{
		// declaration des sessions
		$_SESSION[ $this->password_name ] = $this->user['password'];
		$_SESSION[ $this->login_name ] = $this->user['email'];
		$_SESSION['token'] = $this->fingerprint();

		// déclaration des cookies
		$peremptionCookies = time() + (3600 * 24 * 31); // 31 J
		setcookie( $this->login_name , $this->user['email'], $peremptionCookies, "/");
		setcookie( $this->password_name , $this->user['password'], $peremptionCookies, "/");
		setcookie( 'token' , $_SESSION['token'], $peremptionCookies, "/");
	}

	/*
	 * Reset complet des variables d'identification
	* C'est une déconnexion
	*/
	private function resetSessionData()
	{
		// declaration des sessions
		$_SESSION[ $this->password_name ] = '';
		$_SESSION[ $this->login_name ] = '';
		$_SESSION['token'] = '';

		// déclaration des cookies
		$peremptionCookies = time() - (3600 * 24 * 31 * 365); // - 1 an
		setcookie( $this->login_name , '', $peremptionCookies, "/");
		setcookie( $this->password_name , '', $peremptionCookies, "/");
		setcookie( 'token' , '', $peremptionCookies, "/");

		$this->connected = false;
		$this->user = array();
	}

	/*
	 * Mise à jours de divers infos de connexion dans la BDD
	* $id : int du user
	* $connexion : 0 ou 1
	*     => 0 : test de connexion
	*     => 1 : connexion
	*/
	private function updateUser($id, $connexion=0)
	{
		$date = time();

		$addreq = ($connexion == 1) ? ", date_last_connexion='$date'" : "";

		$sql = "UPDATE ".$this->user_table_name." SET date_last_action='$date'$addreq WHERE id='$id'";
		if(!mysql_query($sql))
			exit('Erreur MySQL : Impossible de mettre les informations de l\'utilisateur à jours.');
	}

}
